
#include "mpi.h"
#include <cassert>
#include <iostream>

using namespace std;

int main(int argc, char **argv) {

  int my_rank, num_proc;
  MPI_Init(&argc, &argv);
  MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
  MPI_Comm_size(MPI_COMM_WORLD, &num_proc);

  int *val, flag;
  MPI_Comm_get_attr(MPI_COMM_WORLD, MPI_APPNUM, &val, &flag);

  //   cout << num_proc << " **** " << my_rank << " **** " << *val << endl;

  MPI_Comm group_comm;
  MPI_Comm_split(MPI_COMM_WORLD, *val, my_rank, &group_comm);

  int my_group_rank, group_num_proc;
  MPI_Comm_rank(group_comm, &my_group_rank);
  MPI_Comm_size(group_comm, &group_num_proc);

  if (my_group_rank == 0) {
    int ranks[group_num_proc];
    MPI_Gather(&my_group_rank, 1, MPI_INT, ranks, 1, MPI_INT, 0, group_comm);
    for (int i = 0; i < group_num_proc; ++i)
      cout << ranks[i] << " ** ";
    cout << endl;
  } else {
    MPI_Gather(&my_group_rank, 1, MPI_INT, nullptr, 1, MPI_INT, 0, group_comm);
  }

  int is_world_exist{-1};
  if (my_rank == 0) {
    is_world_exist = 1;
  }
  MPI_Bcast(&is_world_exist, 1, MPI_INT, 0, MPI_COMM_WORLD);

  cout << is_world_exist << endl;

  MPI_Finalize();
  return 0;
}